/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Service;

import Constants.Command;
import Constants.PIConstants;
import Constants.Service;
import DataManager.DbManager;
import DataManager.MySQLCommonDataProvider;

import Shared.PrivateMessage;
import DataManager.VCoreUserDataProvider;
import PIServer.VMSProtocolHandler;
import Shared.ItemObj;
import Message.Message;
import org.apache.mina.core.session.IoSession;
import Message.SerializerHelper;
import java.util.ArrayList;
import Message.DateTime;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import vcore.obj.vcoreUser;

/**
 *
 * @author nguyendn
 */
@SuppressWarnings("deprecation")
public class UserService {

    public static Logger log = LoggerFactory.getLogger(UserService.class.getName());

    public static void ProcessCommand(IoSession session, int userID, String userName, Message clientMsg) {

        int actionCommand = clientMsg.getActionCommand();
        switch (actionCommand) {
            case Command.ADD_FRIEND:
                addFriend(session, userID, userName, clientMsg);
                break;
            case Command.REMOVE_FRIEND:
                removeFriend(session, userID, userName, clientMsg);
                break;
            case Command.LIST_FRIEND:
                listFriend(session, userID);
                break;
            case Command.SEND_PM:
                sendPrivateMessage(session, userID, userName, clientMsg);
                break;
            case Command.REMOVE_PM:
                removePrivateMessage(session, clientMsg);
                break;
            case Command.LIST_PM:
                listPrivateMessage(session, userID, userName, clientMsg);
                break;
            case Command.CHANGE_PASSWORD:
                changePassword(session, userName, clientMsg);
                break;
            case Command.SEND_VIXU:
                sendVixu(session, userID, userName, clientMsg);
                break;
            case Command.CHANGE_FULLNAME:
                log.info("change fullname");
                updateFullname(session, userName, clientMsg);
                break;
            case Command.CHANGE_GENDER:
                log.info("change gender");
                updateGender(session, userName, clientMsg);
                break;
            case Command.CHANGE_BIRTHYEAR:
                log.info("change birth year");
                updateBirthYear(session, userName, clientMsg);
                break;
            case Command.CHANGE_ADDRESS:
                log.info("change address");
                updateAddress(session, userName, clientMsg);
                break;
            case Command.CHANGE_CMND:
                log.info("change fullname");
                updateCMND(session, userName, clientMsg);
                break;
            case Command.CHANGE_MOBILE:
                log.info("change mobile");
                updateMobile(session, userName, clientMsg);
                break;
            case Command.CHANGE_CITY:
                log.info("change city");
                updateCity(session, userName, clientMsg);
                break;
            case Command.REPLY_PM:
                log.info("reply pm");
                replyPM(session, userID, userName, clientMsg);
                break;
            case Command.CHANGE_PM_STATUS:
                log.info("mark read pm");
                markRead(session, userName, clientMsg);
                break;
            case Command.MONEY_TRANSFER:
                log.info("money transfer");
                transferMoney(session, userName, clientMsg);
                break;

            case Command.PERSONAL_ACTION:
                log.info("personal action");
                personalAction(session, userID, userName, clientMsg);
                break;

//            case Command.UPDATE_PERSONAL_INFO:
//                updatePersonalInfo(session, userID, userName, clientMsg);
//                break;

            case Command.GET_USER_INFO:
                getUserInfo(session, userID, userName, clientMsg);
                break;

            case Command.UPDATE_ITEM_STATUS:
                updateItemStatus(session, userID, userName, clientMsg);
                break;

            default:
                break;
        }

    }

    /**
     * Thêm bạn bè
     * @param session
     * @param username
     * @param clientMsg
     * -1: Lỗi hệ thống
     * 0: Kết bạn thành công
     * 1: Đã gửi yêu cầu kết bạn
     * 2: Đã kết bạn rồi
     * 3: Không tìm thấy user
     */
    public static void addFriend(IoSession session, int userID, String userName, Message clientMsg) {
        String toUser = SerializerHelper.readString(clientMsg);
        UserObj userObj = new UserObj();
        try {
            int toUserID = VCoreUserDataProvider.getInstance().GetUserIdByUsername(toUser);

            Message msg = new Message(Command.RESPONSE_ADD_FRIEND, Service.CHAT_SERVICE);
            if (userName.equals(toUser) || (toUserID == 0)) {
                SerializerHelper.writeInt((toUserID == 0) ? 3 : -1, msg);
            } else {
                if (userObj.checkUsernameExists(toUser)) {
                    VCoreUserDataProvider dataManager = DbManager.GetUserDataManager();
                    MySQLCommonDataProvider commonDataManager = DbManager.GetCommonDataManager();
                    if (!commonDataManager.checkFriend(userID, toUserID)) {
                        if (commonDataManager.checkFriendRequestSent(userID, toUserID)) {
                            SerializerHelper.writeInt(1, msg);      // FRIEND REQUEST SENT
                        } else {
                            int result = commonDataManager.createMessage(userID, toUserID, "",
                                    PIConstants.MESSAGE_TYPE_FRIEND_REQUEST);
                            if (result > 0) {
//                            userObj = dataManager.getAccountInfo(toUser);
                                SerializerHelper.writeInt(1, msg);      // FRIEND REQUEST SENT
//                            SerializerHelper.writeString(userObj.username, msg);
//                            SerializerHelper.writeInt(userObj.money, msg);

//                            userObj = commonDataManager.getUserServiceInfoByUserID(userObj.userid);
//                            SerializerHelper.writeInt(userObj.avatar, msg);
//                            SerializerHelper.writeInt(userObj.nickColor, msg);
//                            SerializerHelper.writeString(userObj.emotion_status, msg);
//                            SerializerHelper.writeInt(userObj.user_level,msg);

                                IoSession s = VMSProtocolHandler.getSessionByUserID(toUserID);
                                if (s != null && s.isConnected()) {
                                    Message toMsg = new Message(Command.RESPONSE_NEW_PM, Service.CHAT_SERVICE);
//                                userObj = dataManager.getAccountInfo(userName);
                                    SerializerHelper.writeInt(result, toMsg);       // message id
                                    SerializerHelper.writeString(userName, toMsg);  // sender
                                    SerializerHelper.writeInt(userID, toMsg);   // sender id
                                    SerializerHelper.writeString("", toMsg);  // content
                                    SerializerHelper.writeInt(PIConstants.MESSAGE_TYPE_FRIEND_REQUEST, toMsg); // message type
                                    SerializerHelper.writeDateTime(null, toMsg);  // sender
//                                SerializerHelper.writeInt(userObj.money, toMsg);
//                                userObj = commonDataManager.getUserServiceInfoByUserID(userID);
//                                SerializerHelper.writeInt(userObj.avatar, toMsg);
//                                SerializerHelper.writeInt(userObj.nickColor, toMsg);
//                                SerializerHelper.writeString(userObj.emotion_status, toMsg);
                                    s.write(toMsg);
                                }
                                dataManager.closeConnection();
                                commonDataManager.closeConnection();
                            } else {
                                SerializerHelper.writeInt(-1, msg);          // ADD FRIEND FAIL
                            }
                        }
                    } else {
                        SerializerHelper.writeInt(2, msg);     // ALREADY FRIEND
                    }
                } else {
                    SerializerHelper.writeInt(3, msg);     // USER NOT FOUND
                }
            }
            session.write(msg);
        } catch (Exception ex) {
            log.error("addFriend", ex);
            //ex.printStackTrace();
        }
    }

    public static void listFriend(IoSession session, int userID) {
        try {
            VCoreUserDataProvider dataManager = new VCoreUserDataProvider();
            MySQLCommonDataProvider commonDataManager = DbManager.GetCommonDataManager();
            Message msg = new Message(Command.RESPONSE_LIST_FRIEND, Service.CHAT_SERVICE);
            //SerializerHelper.writeString("INCOMING_USER_VALUE~"+dataManager.getAccountInfo(userName),msg);
            //session.write(msg);
            ArrayList userList = commonDataManager.getFriendList(userID);

            SerializerHelper.writeInt(userList.size(), msg);
            for (int i = 0; i < userList.size(); i++) {
                UserObj userObj = (UserObj) userList.get(i);
                SerializerHelper.writeInt(userObj.userid, msg);
                SerializerHelper.writeString(userObj.username, msg);
                SerializerHelper.writeInt(userObj.gender, msg);
                IoSession s = VMSProtocolHandler.getSessionByUserID(userObj.userid);
                SerializerHelper.writeBoolean((s != null && s.isConnected()), msg); // is online
            }
            session.write(msg);
            dataManager.closeConnection();
            commonDataManager.closeConnection();
        } catch (Exception ex) {
            log.error("listFriend", ex);
        }
    }

    public static void removeFriend(IoSession session, int userID, String username, Message clientMsg) {

        int numOfFriend = SerializerHelper.readInt(clientMsg);
        int[] friendID = new int[numOfFriend];

        try {
            MySQLCommonDataProvider dataManager = DbManager.GetCommonDataManager();
            Message msg = new Message(Command.RESPONSE_REMOVE_FRIEND, Service.CHAT_SERVICE);
            boolean result = true;
            for (int i=0; i<numOfFriend; i++) {
                friendID[i] = SerializerHelper.readInt(clientMsg);
                result = dataManager.removeFriend(friendID[i], userID);
                if (!result) {
                    break;
                }
            }

            if (result) {
                SerializerHelper.writeInt(1, msg);
                SerializerHelper.writeInt(numOfFriend, msg);
                for (int i=0; i<numOfFriend; i++) {
                    SerializerHelper.writeInt(friendID[i], msg);
                }
            } else {
                SerializerHelper.writeInt(0, msg);
            }
            session.write(msg);
            dataManager.closeConnection();
        } catch (Exception ex) {
            log.error("removeFriend", ex);
        }
    }

    public static void sendPrivateMessage(IoSession session, int userID, String userName, Message clientMsg) {
        //String fromUser = SerializerHelper.readString(clientMsg);
        int recipientID = SerializerHelper.readInt(clientMsg);
        String text = SerializerHelper.readString(clientMsg);
        text = ServerService.filterChatMessage(text);
        try {
//            int toUserID = VCoreUserDataProvider.getInstance().GetUserIdByUsername(recipientID);
            MySQLCommonDataProvider dataManager = DbManager.GetCommonDataManager();
            Message msg = new Message(Command.RESPONSE_SEND_PM, Service.CHAT_SERVICE);
            int result = dataManager.createMessage(userID, recipientID, text, PIConstants.MESSAGE_TYPE_NORMAL);
            SerializerHelper.writeBoolean((result > 0), msg);
            session.write(msg);

            if (result > 0) {
                if (recipientID == 0) {
                    try {
                        int introUserID = Integer.parseInt(text);
                        if (introUserID != userID
                                && dataManager.addUserIntroductionPromotion(introUserID, userID)) { // check promotion message
                            int newUserMoney = dataManager.retrieveAccountBalance(userID);
                            int introUserMoney = dataManager.retrieveAccountBalance(introUserID);
                            String introUser = VCoreUserDataProvider.getInstance().GetUserNamebyId(introUserID);
                            dataManager.setUserMoney(userID, newUserMoney + 20000, StringConstant.strPromotionGiftLog, 20000, CardConstant.INTRODUCE_EVENT_MONEY_TYPE, CardConstant.ITEM_SERVICE_ID, -1);
                            dataManager.setUserMoney(introUserID, introUserMoney + 50000, StringConstant.strPromotionBonusLog, 50000,CardConstant.INTRODUCE_EVENT_MONEY_TYPE, CardConstant.ITEM_SERVICE_ID, -1);
                            dataManager.createMessage(0, userID, String.format(StringConstant.strPromotionGiftMessage, 20000, introUser), PIConstants.MESSAGE_TYPE_NORMAL);
                            dataManager.createMessage(0, introUserID, String.format(StringConstant.strPromotionBonusMessage, 50000, userName), PIConstants.MESSAGE_TYPE_NORMAL);
//                            dataManager.updateMessageStatus(result, 0); // xóa tin nhắn giới thiệu
                        } else {
                            log.debug("Invalid promotion message {} - {}", introUserID, userID);
                            dataManager.createMessage(0, userID, String.format(StringConstant.strPromotionErrorMessage), PIConstants.MESSAGE_TYPE_NORMAL);
                        }
                    } catch (NumberFormatException e) {
                        log.error("NumberFormatException ", e.getMessage());
                    }
                } else {
                    IoSession toUserSession = VMSProtocolHandler.getSessionByUserID(recipientID);
                    if (toUserSession != null) {
                        Date date = new Date();
                        DateTime d = new DateTime(date.getYear() + 1900,
                                date.getMonth() + 1,
                                date.getDate(),
                                date.getHours(),
                                date.getMinutes(),
                                date.getSeconds(),
                                0);

                        Message msg1 = new Message(Command.RESPONSE_NEW_PM, Service.CHAT_SERVICE);
                        SerializerHelper.writeInt(result, msg1);         // message id
                        SerializerHelper.writeString(userName, msg1);    // sender
                        SerializerHelper.writeInt(userID, msg1);         // sender id
                        SerializerHelper.writeString(text, msg1);        // content
                        SerializerHelper.writeInt(PIConstants.MESSAGE_TYPE_NORMAL, msg1); // message type
//                        SerializerHelper.writeInt(dataManager.getUserAvatar(userID), msg1); // sender avatar
                        SerializerHelper.writeDateTime(d, msg1); // datetime
//                        SerializerHelper.writeInt(dataManager.getNickColor(userID), msg1); // sender nick color
                        toUserSession.write(msg1);
                    }
                }
            }
            dataManager.closeConnection();
        } catch (Exception ex) {
            log.error("sendPrivateMessage", ex);
            //ex.printStackTrace();
        }
    }

    public static void markRead(IoSession session, String username, Message clientMsg) {
        int pmId = SerializerHelper.readInt(clientMsg);
        try {
            MySQLCommonDataProvider dataManager = DbManager.GetCommonDataManager();
            dataManager.updateMessageViewStatus(pmId, 1);
        } catch (Exception ex) {
            log.error("markRead", ex);
        }
    }

    public static void replyPM(IoSession session, int userID, String userName, Message clientMsg) {
        //String fromUser = SerializerHelper.readString(clientMsg);
        int pmId = SerializerHelper.readInt(clientMsg);
        int msgType = SerializerHelper.readInt(clientMsg);
        int recipientID = SerializerHelper.readInt(clientMsg);
        String text = SerializerHelper.readString(clientMsg);

        try {
            MySQLCommonDataProvider commonDataManager = DbManager.GetCommonDataManager();

            if (msgType == PIConstants.MESSAGE_TYPE_FRIEND_REQUEST) {
                if (text.equals("1")) { // accept friend request
                    if (!commonDataManager.checkFriend(userID, recipientID)) {
                        boolean result = commonDataManager.addFriend(userID, recipientID);
                        Message msg = new Message(Command.RESPONSE_ADD_FRIEND, Service.CHAT_SERVICE);
                        if (result) {
                            VCoreUserDataProvider dataManager = DbManager.GetUserDataManager();
                            UserObj userObj = dataManager.getAccountInfo(recipientID);
                            SerializerHelper.writeInt(0, msg);
                            SerializerHelper.writeString(userObj.username, msg);
                            session.write(msg);

                            IoSession s = VMSProtocolHandler.getSessionByUserID(recipientID);
                            if (s != null && s.isConnected()) {
                                msg.getBuffer().setPosition(0);
                                SerializerHelper.writeInt(0, msg);
                                SerializerHelper.writeString(userName, msg);
                                s.write(msg);
                            }
                        } else {
                            SerializerHelper.writeInt(-1, msg);
                            session.write(msg);
                        }
                    } else {
                        // todo: send error
                    }
                }
                commonDataManager.updateMessageStatus(pmId, PIConstants.MESSAGE_STATUS_REMOVED);
                return;
            }

            commonDataManager.updateMessageViewStatus(pmId, 2);
//            int toUserID = VCoreUserDataProvider.getInstance().GetUserIdByUsername(recipientID);
            Message msg = new Message(Command.RESPONSE_REPLY_PM, Service.CHAT_SERVICE);
            int result = commonDataManager.createMessage(userID, recipientID, text, PIConstants.MESSAGE_TYPE_NORMAL);
            SerializerHelper.writeBoolean((result > 0), msg);
            session.write(msg);
            /**
             * push message
             */
            if (result > 0) {
                IoSession toUserSession = VMSProtocolHandler.getSessionByUserID(recipientID);
                if (toUserSession != null) {
                    Date date = new Date();
                    DateTime d = new DateTime(date.getYear() + 1900,
                            date.getMonth() + 1,
                            date.getDate(),
                            date.getHours(),
                            date.getMinutes(),
                            date.getSeconds(),
                            0);

                    Message msg1 = new Message(Command.RESPONSE_NEW_PM, Service.CHAT_SERVICE);
                    SerializerHelper.writeInt(result, msg1);         // message id
                    SerializerHelper.writeString(userName, msg1);    // sender
                    SerializerHelper.writeInt(userID, msg1);    // sender id
                    SerializerHelper.writeString(text, msg1);        // content
//                    SerializerHelper.writeInt(dataManager.getUserAvatar(userID), msg1);    // sender avatar
                    SerializerHelper.writeInt(PIConstants.MESSAGE_TYPE_NORMAL, msg1); // message type
                    SerializerHelper.writeDateTime(d, msg1); // datetime
//                    SerializerHelper.writeInt(dataManager.getNickColor(userID), msg1); // sender nick color
                    toUserSession.write(msg1);
                }
            }
            /**
             * end push
             */
            commonDataManager.closeConnection();
        } catch (Exception ex) {
            log.error("replyPM", ex);
            //ex.printStackTrace();
        }
    }

    public static void listPrivateMessage(IoSession session, int userID, String userName, Message clientMsg) {
        //String toUser   = SerializerHelper.readString(clientMsg);
        try {
            MySQLCommonDataProvider dataManager = DbManager.GetCommonDataManager();
            Message msg = new Message(Command.RESPONSE_LIST_PM, Service.CHAT_SERVICE);
            ArrayList pmList = dataManager.getInboxMessage(userID);
            SerializerHelper.writeInt(pmList.size(), msg);              // messages num
            for (int i = 0; i < pmList.size(); i++) {
                PrivateMessage pmObj = (PrivateMessage) pmList.get(i);
                SerializerHelper.writeInt(pmObj.messageId, msg);        // id
                SerializerHelper.writeString(pmObj.senderName, msg);      // sender
                SerializerHelper.writeInt(pmObj.senderId, msg);       // sender id
//                SerializerHelper.writeString(pmObj.senderEmotion, msg); // sender emotion
                SerializerHelper.writeString(pmObj.text, msg);          // content
//                SerializerHelper.writeInt(pmObj.senderAvatar, msg);     // sender avatar
                SerializerHelper.writeInt(pmObj.msgType, msg);           // status
                SerializerHelper.writeInt(pmObj.type, msg);           // status
                SerializerHelper.writeDateTime(pmObj.sentTime, msg); // datetime
//                SerializerHelper.writeInt(pmObj.senderNickColor, msg);           // status
            }
            session.write(msg);
            dataManager.closeConnection();
        } catch (Exception ex) {
            log.error("listPrivateMessage", ex);
            //ex.printStackTrace();
        }
    }

    public static void removePrivateMessage(IoSession session, Message clientMsg) {
        int msgNum = SerializerHelper.readInt(clientMsg);
        for (int i = 0; i < msgNum; i++) {
            int pmId = SerializerHelper.readInt(clientMsg);
            try {
                MySQLCommonDataProvider dataManager = DbManager.GetCommonDataManager();
                boolean result = dataManager.updateMessageStatus(pmId, PIConstants.MESSAGE_STATUS_REMOVED);
                Message msg = new Message(Command.RESPONSE_REMOVE_PM, Service.CHAT_SERVICE);
                SerializerHelper.writeBoolean(result, msg);
                session.write(msg);
            } catch (Exception ex) {
                log.error("removePrivateMessage", ex);
            }
        }
    }

    private static void changePassword(IoSession session, String username, Message clientMsg) {
        String currentPass = SerializerHelper.readString(clientMsg);
        String newPass = SerializerHelper.readString(clientMsg);
        String confirmNewPass = SerializerHelper.readString(clientMsg);
        try {
            Message msg = new Message(Command.RESPONSE_CHANGE_PASSWORD, Service.CHAT_SERVICE);
            VCoreUserDataProvider dataManager = new VCoreUserDataProvider();
            int result = Command.CHANGEPASS_FAILED;
            if ((dataManager.isAuthenticated(username, currentPass) == 1)
                    && (newPass.equals(confirmNewPass))
                    && (dataManager.changePassword(username, currentPass, newPass))) {
                result = Command.CHANGEPASS_SUCCESS;
                //SerializerHelper.writeString("SUCCESS",msg);
            }
            SerializerHelper.writeInt(result, msg);
            session.write(msg);
            dataManager.closeConnection();
        } catch (Exception ex) {
            log.error("changePassword", ex);
        }
    }

    private static void sendVixu(IoSession session, int userID, String userName, Message clientMsg) {
        String toUser = SerializerHelper.readString(clientMsg);
        int money = SerializerHelper.readInt(clientMsg);
        UserObj userObj = new UserObj();
        try {
            Message msg = new Message(Command.RESPONSE_SEND_VIXU, Service.CHAT_SERVICE);
            MySQLCommonDataProvider dataManager = DbManager.GetCommonDataManager();
            if (userObj.checkUsernameExists(toUser)) {
                int balanceSender = dataManager.retrieveAccountBalance(userID);
                if (balanceSender < money) {
                    int balanceSenderNew = balanceSender - money;
                    int balanceReceiver = dataManager.retrieveAccountBalance(toUser);
                    int balanceReceiverNew = balanceReceiver + money;
                    String desc = String.format(StringConstant.strTransferMoney, userName, toUser);
                    if ((dataManager.setUserMoney(userID, balanceSenderNew, desc, money, CardConstant.TRANFER_MONEY_TYPE, CardConstant.ITEM_SERVICE_ID, -1)
                            && (dataManager.setUserMoney(toUser, balanceReceiverNew, desc, money, CardConstant.TRANFER_MONEY_TYPE, CardConstant.ITEM_SERVICE_ID, -1)))) {
                        SerializerHelper.writeString("SUCCESS", msg);
                    } else {
                        SerializerHelper.writeString("FAILD", msg);
                    }
                } else {
                    //Không đủ tiền gửi
                    SerializerHelper.writeString("MONEY_INVALID", msg);
                }
            } else {
                //Không tồn tại user
                SerializerHelper.writeString("USER_INVALID", msg);
            }
            session.write(msg);
            dataManager.closeConnection();
        } catch (Exception ex) {
            log.error("sendVixu", ex);
        }
    }

    private static void updateFullname(IoSession session, String username, Message clientMsg) {
        String fullname = SerializerHelper.readString(clientMsg);
        try {
            Message msg = new Message(Command.RESPONSE_CHANGE_FULLNAME, Service.CHAT_SERVICE);
            VCoreUserDataProvider dataManager = DbManager.GetUserDataManager();
            UserObj user = dataManager.getAccountInfo(username);
            user.fullname = fullname;
            if (dataManager.updateAccountInfo(user)) {
                SerializerHelper.writeString("SUCCESS", msg);
            } else {
                SerializerHelper.writeString("FAILD", msg);
            }
            session.write(msg);
            dataManager.closeConnection();
        } catch (Exception ex) {
            log.error("updateFullname", ex);
        }
    }

    private static void updateGender(IoSession session, String username, Message clientMsg) {
        int gender = SerializerHelper.readInt(clientMsg);
        try {
            Message msg = new Message(Command.RESPONSE_CHANGE_GENDER, Service.CHAT_SERVICE);
            VCoreUserDataProvider dataManager = DbManager.GetUserDataManager();
            UserObj user = dataManager.getAccountInfo(username);
            user.gender = (byte) gender;
            if (dataManager.updateAccountInfo(user)) {
                SerializerHelper.writeString("SUCCESS", msg);
            } else {
                SerializerHelper.writeString("FAILD", msg);
            }
            session.write(msg);
            dataManager.closeConnection();
        } catch (Exception ex) {
            log.error("updateGender", ex);
        }
    }

    private static void updateBirthYear(IoSession session, String username, Message clientMsg) {
        int birthYear = SerializerHelper.readInt(clientMsg);
        try {
            Message msg = new Message(Command.RESPONSE_CHANGE_BIRTHYEAR, Service.CHAT_SERVICE);
            VCoreUserDataProvider dataManager = DbManager.GetUserDataManager();
            UserObj user = dataManager.getAccountInfo(username);
            user.birth_year = birthYear;
            if (dataManager.updateAccountInfo(user)) {
                SerializerHelper.writeString("SUCCESS", msg);
            } else {
                SerializerHelper.writeString("FAILD", msg);
            }
            session.write(msg);
            dataManager.closeConnection();
        } catch (Exception ex) {
            log.error("updateBirthYear", ex);
        }
    }

    private static void updateAddress(IoSession session, String username, Message clientMsg) {
        String address = SerializerHelper.readString(clientMsg);
        try {
            Message msg = new Message(Command.RESPONSE_CHANGE_ADDRESS, Service.CHAT_SERVICE);
            VCoreUserDataProvider dataManager = DbManager.GetUserDataManager();
            UserObj user = dataManager.getAccountInfo(username);
            user.address = address;
            if (dataManager.updateAccountInfo(user)) {
                SerializerHelper.writeString("SUCCESS", msg);
            } else {
                SerializerHelper.writeString("FAILD", msg);
            }
            session.write(msg);
            dataManager.closeConnection();
        } catch (Exception ex) {
            log.error("updateAddress", ex);
        }
    }

    private static void updateCMND(IoSession session, String username, Message clientMsg) {
        String cmnd = SerializerHelper.readString(clientMsg);
        try {
            Message msg = new Message(Command.RESPONSE_CHANGE_CMND, Service.CHAT_SERVICE);
            VCoreUserDataProvider dataManager = DbManager.GetUserDataManager();
            UserObj user = dataManager.getAccountInfo(username);
            user.cmnd = cmnd;
            if (dataManager.updateAccountInfo(user)) {
                SerializerHelper.writeString("SUCCESS", msg);
            } else {
                SerializerHelper.writeString("FAILD", msg);
            }
            session.write(msg);
            dataManager.closeConnection();
        } catch (Exception ex) {
            log.error("updateCMND", ex);
        }
    }

    private static void updateMobile(IoSession session, String username, Message clientMsg) {
        String mobile = SerializerHelper.readString(clientMsg);
        try {
            Message msg = new Message(Command.RESPONSE_CHANGE_MOBILE, Service.CHAT_SERVICE);
            VCoreUserDataProvider dataManager = DbManager.GetUserDataManager();
            UserObj user = dataManager.getAccountInfo(username);
            user.mobile = mobile;
            if (dataManager.updateAccountInfo(user)) {
                SerializerHelper.writeString("SUCCESS", msg);
            } else {
                SerializerHelper.writeString("FAILD", msg);
            }
            session.write(msg);
            dataManager.closeConnection();
        } catch (Exception ex) {
            log.error("updateMobile", ex);
        }
    }

    private static void updateCity(IoSession session, String username, Message clientMsg) {
        int city = SerializerHelper.readInt(clientMsg);
        try {
            Message msg = new Message(Command.RESPONSE_CHANGE_CITY, Service.CHAT_SERVICE);
            VCoreUserDataProvider dataManager = DbManager.GetUserDataManager();
            UserObj user = dataManager.getAccountInfo(username);
            user.city = city;
            if (dataManager.updateAccountInfo(user)) {
                SerializerHelper.writeString("SUCCESS", msg);
            } else {
                SerializerHelper.writeString("FAILD", msg);
            }
            session.write(msg);
            dataManager.closeConnection();
        } catch (Exception ex) {
            log.error("updateCity", ex);
        }
    }

//    public static void notifyNewMessage(int mess_id, int sender_id, int toUserID, String text) {
//        IoSession toUserSession = VMSProtocolHandler.getSessionByUserID(toUserID);
//        MySQLCommonDataProvider commonDataManager = DbManager.GetCommonDataManager();
//        try {
//            if (toUserSession != null) {
//                Date date = new Date();
//                DateTime d = new DateTime(date.getYear() + 1900,
//                        date.getMonth() + 1,
//                        date.getDate(),
//                        date.getHours(),
//                        date.getMinutes(),
//                        date.getSeconds(),
//                        0);
//                String sendUsername = VCoreUserDataProvider.getInstance().GetUserNamebyId(sender_id);
//                Message msg1 = new Message(Command.RESPONSE_NEW_PM, Service.CHAT_SERVICE);
//                SerializerHelper.writeInt(mess_id, msg1);         // message id
//                SerializerHelper.writeString(sendUsername, msg1);    // sender
//                SerializerHelper.writeString(text, msg1);        // content
//                SerializerHelper.writeInt(commonDataManager.getUserAvatar(sender_id), msg1);    // sender avatar
//                SerializerHelper.writeDateTime(d, msg1); // datetime
//                SerializerHelper.writeInt(commonDataManager.getNickColor(sender_id), msg1); // sender nick color
//                toUserSession.write(msg1);
//            }
//        }
//        catch (Exception ex) {
//            log.error("notifyNewMessage", ex);
//        }
//        finally {
//            commonDataManager.closeConnection();
//        }
//
//    }



//    private static long calcExpOnLvListNew(int number, int[] lvArray, int[] amountArray) {
//        long totalExp = 0;
//        try {
//            if ((number > lvArray[0]) && (number <= lvArray[1])) {
//                totalExp = number * amountArray[1];
//            } else if ((number > lvArray[1]) && (number <= lvArray[2])) {
//                totalExp = (number - lvArray[1]) * amountArray[2] + (lvArray[1] * amountArray[1]);
//
//            } else if ((number > lvArray[2]) && (number <= lvArray[3])) {
//              long tmpExp = 0;
//                for(int i=1;i<3;i++)
//                {
//                    tmpExp+=(lvArray[i]-lvArray[i-1])*amountArray[i];
//                }
//                totalExp = ((number-lvArray[2]) * amountArray[3]) + tmpExp;
//
//            } else if ((number > lvArray[3]) && (number <= lvArray[4])) {
//                long tmpExp = 0;
//                for(int i=1;i<4;i++)
//                {
//                    tmpExp+=(lvArray[i]-lvArray[i-1])*amountArray[i];
//                }
//                totalExp = ((number-lvArray[3]) * amountArray[4]) + tmpExp;
//
//            } else if ((number > lvArray[4]) && (number <= lvArray[5])) {
//                long tmpExp = 0;
//                for(int i=1;i<5;i++)
//                {
//                    tmpExp+=(lvArray[i]-lvArray[i-1])*amountArray[i];
//                }
//                totalExp = ((number-lvArray[4]) * amountArray[5]) + tmpExp;
//
//            } else if (number > lvArray[5]) {
//                long tmpExp = 0;
//                for(int i=1;i<6;i++)
//                {
//                    tmpExp+=(lvArray[i]-lvArray[i-1])*amountArray[i];
//                }
//                totalExp = ((number-lvArray[5]) * amountArray[6]) + tmpExp;
//            }
//
//        } catch (Exception e) {
//            log.error(e.getClass().getName(), e);
//        }
//        return totalExp;
//    }

    private static void transferMoney(IoSession session, String userName, Message clientMsg) {
//        MySQLCommonDataProvider commonDataManager = DbManager.GetCommonDataManager();
        try {
            String toUser = SerializerHelper.readString(clientMsg);
            int money = SerializerHelper.readInt(clientMsg);
            int userID = (Integer) session.getAttribute("userid");

            boolean retVal = false;
            vcoreUser userInfoObj = VCoreUserDataProvider.getInstance().GetInfobyUserid(userID);
            if (userInfoObj.user_type == 3)  {
                retVal = ServerService.transferMoney(userID, userName, toUser, money);
            }

            Message msg = new Message(Command.RESPONSE_MONEY_TRANSFER, Service.CHAT_SERVICE);
            SerializerHelper.writeInt(retVal?1:0, msg); // result OK or not
            SerializerHelper.writeString(toUser, msg); // user received
            SerializerHelper.writeInt(money, msg);    // money sent
            session.write(msg);
        }
        catch (Exception ex) {
            log.error("transferMoney", ex);
        }
        finally {
//            commonDataManager.closeConnection();
        }
    }

    private static void personalAction(IoSession session, int userID, String userName, Message clientMsg) {

        int action = SerializerHelper.readInt(clientMsg);
        int mapID = (Integer) session.getAttribute("map",-1);
            Message msg = new Message(Command.RESPONSE_PERSONAL_ACTION, Service.CHAT_SERVICE);
            SerializerHelper.writeInt(mapID, msg);
            SerializerHelper.writeInt(userID, msg);
            SerializerHelper.writeInt(action, msg);
            ServerService.broadcastMap(mapID, msg, userName);
    }

//    private static void updatePersonalInfo(IoSession session, int userID, String userName, Message clientMsg) {
//        int gender = SerializerHelper.readInt(clientMsg);
//        int hair = SerializerHelper.readInt(clientMsg);
//        try {
//            Message msg = new Message(Command.RESPONSE_CHANGE_GENDER, Service.CHAT_SERVICE);
//            VCoreUserDataProvider dataManager = DbManager.GetUserDataManager();
//            UserObj user = dataManager.getAccountInfo(userName);
//            user.gender = (byte) gender;
//            user.hair = (byte) hair;
//            if (dataManager.updateAccountInfo(user)) {
//                SerializerHelper.writeBoolean(true, msg);
//            } else {
//                SerializerHelper.writeBoolean(false, msg);
//            }
//            session.write(msg);
//            dataManager.closeConnection();
//        } catch (Exception ex) {
//            log.error("update personal info", ex);
//        }
//    }

    private static void getUserInfo(IoSession session, int userID, String userName, Message clientMsg) {
        int userId = SerializerHelper.readInt(clientMsg);
        try {
            VCoreUserDataProvider dataManager = DbManager.GetUserDataManager();
            MySQLCommonDataProvider commonDataManager = DbManager.GetCommonDataManager();
            CharacterObj charObj = commonDataManager.loadCharacterData(userId);
            UserObj userObj = dataManager.getAccountInfo(userId);
            ArrayList itemList = commonDataManager.getUserInventory(userId);

            int result = (charObj != null && userObj != null && itemList != null) ? 1 : 0;
            Message msg = new Message(Command.RESPONSE_GET_USER_INFO, Service.CHAT_SERVICE);
            SerializerHelper.writeInt(result, msg);
            if (result == 1) {
                SerializerHelper.writeString(userObj.username, msg);
                SerializerHelper.writeInt(userObj.user_level, msg);
                SerializerHelper.writeInt(1, msg);  // farm level
                SerializerHelper.writeInt(userObj.money, msg);
                SerializerHelper.writeInt(0, msg);  // farm money
                SerializerHelper.writeByte(charObj.sex, msg);
                SerializerHelper.writeByte(charObj.hair, msg);
                SerializerHelper.writeByte(charObj.head, msg);
                SerializerHelper.writeByte(charObj.eyes, msg);
                SerializerHelper.writeByte(charObj.emotion, msg);
                SerializerHelper.writeByte(charObj.shirt, msg);
                SerializerHelper.writeByte(charObj.pant, msg);
                SerializerHelper.writeByte(charObj.headItem, msg);
                SerializerHelper.writeByte(charObj.handItem, msg);
                SerializerHelper.writeByte(charObj.faceItem, msg);
                SerializerHelper.writeByte(charObj.petType, msg);
                SerializerHelper.writeByte(charObj.petHealth, msg);
                SerializerHelper.writeByte(charObj.idxFriendly, msg);
                SerializerHelper.writeByte(charObj.idxHappy, msg);
                SerializerHelper.writeByte(charObj.idxHealthy, msg);
                SerializerHelper.writeByte(charObj.idxHostility, msg);
                SerializerHelper.writeByte(charObj.idxStylish, msg);
                SerializerHelper.writeInt(itemList.size(), msg);
                for (int i=0; i<itemList.size(); i++) {
                    ItemObj item = (ItemObj) itemList.get(i);
                    SerializerHelper.writeInt(item.inventory_id, msg);
                    SerializerHelper.writeInt(item.id, msg);
                    SerializerHelper.writeString(item.name, msg);
                    SerializerHelper.writeInt(item.category, msg);
                    SerializerHelper.writeInt(item.level, msg);
                    SerializerHelper.writeDateTime(item.creation_date, msg);
                    SerializerHelper.writeDateTime(item.expired_date, msg);
                    SerializerHelper.writeInt(item.usages, msg);
                    SerializerHelper.writeInt(item.status, msg);
//                    SerializerHelper.writeInt(getExtraRequirement(item.id), msg);
                }
            }
            session.write(msg);
        } catch (Exception e) {
            log.error("get user info", e);
        }
    }

    private static void updateItemStatus(IoSession session, int userID, String userName, Message clientMsg) {
        int inventoryID = SerializerHelper.readInt(clientMsg);
        int status = SerializerHelper.readInt(clientMsg);

        try {
            int result = 0;
            Message msg = new Message(Command.RESPONSE_UPDATE_ITEM_STATUS, Service.CHAT_SERVICE);
            MySQLCommonDataProvider commonDataManager = DbManager.GetCommonDataManager();

            ItemObj item = commonDataManager.getUserItem(inventoryID);
            if (status == PIConstants.ITEM_STATUS_UNUSED) {
                result = commonDataManager.updateUserInventoryStatus(inventoryID, status);
                if (item.styleIndex > 0) {
                    ParadiseService.updateUserIndex(userID, PIConstants.USER_INDEX_STYLISH, -item.styleIndex);
                }

                if (item.category == PIConstants.ITEM_CATEGORY_ON_FACE
                            || item.category == PIConstants.ITEM_CATEGORY_IN_HAND
                            || item.category == PIConstants.ITEM_CATEGORY_ON_HEAD) {
                    commonDataManager.updateCharacterItem(userID, item.category, 0);
                }

            } else {
                UserObj user = commonDataManager.getUserServiceInfoByUserID(userID);
                if (item.level > 1 && item.level > user.user_level) {
                    SerializerHelper.writeInt(2, msg);
                    session.write(msg);
                    return;
                }

                if (item.healthIndex > 0) {
                    ParadiseService.updateUserIndex(userID, PIConstants.USER_INDEX_HEALTHY, item.healthIndex);
                    // todo: remove user item
                } else if (item.styleIndex > 0) {
                    ParadiseService.updateUserIndex(userID, PIConstants.USER_INDEX_STYLISH, item.styleIndex);
                }

                if (item.usages > 0) {
                    result = commonDataManager.updateUserItemUsages(userID, inventoryID, item.usages-1);
                    // todo: use item
                } else {
                    // neu la do vat mang theo nguoi thi phai cat do cu (quan, ao ...)
                    // va cap nhat lai character
                    if (item.category == PIConstants.ITEM_CATEGORY_ON_FACE
                            || item.category == PIConstants.ITEM_CATEGORY_IN_HAND
                            || item.category == PIConstants.ITEM_CATEGORY_ON_HEAD
                            || item.category == PIConstants.ITEM_CATEGORY_PANT
                            || item.category == PIConstants.ITEM_CATEGORY_SHIRT) {
                        ArrayList itemList = commonDataManager.getUserInventory(userID);
                        for (int i=0; i<itemList.size(); i++) {
                            ItemObj item1 = (ItemObj) itemList.get(i);
                            if (item1.status == PIConstants.ITEM_STATUS_USING
                                    && item1.category == item.category) {
                                commonDataManager.updateUserInventoryStatus(item1.inventory_id,
                                        PIConstants.ITEM_STATUS_UNUSED);
                                break;
                            }
                        }
                        commonDataManager.updateCharacterItem(userID, item.category, item.id);
                    }

                    result = commonDataManager.updateUserInventoryStatus(inventoryID, status);
                }
            }

            SerializerHelper.writeInt(result, msg);
            SerializerHelper.writeInt(inventoryID, msg);
            SerializerHelper.writeInt(status, msg);
            session.write(msg);

        } catch (Exception ex) {
            log.error("Use Item", ex);
        }
    }
}